<!--
 * @Author: mayijun
 * @Date: 2022-07-18 18:37:55
 * @LastEditors: mayijun
 * @LastEditTime: 2022-08-11 14:42:13
-->
<!-- 内容编辑组件 -->
<script lang="ts" setup>
import API from '@/services';
import { onMounted, PropType, reactive, ref, watch } from 'vue';
import MertricsTab from './mertricsTab.vue';
import MertricsDrawer from './mertricsDrawer.vue';
import _ from 'lodash';
import { useRoute } from 'vue-router';

const props = defineProps({
  metricsId: {
    type: String,
    default: () => ''
  },
  //编辑类型：0指标开发，1指标定义
  type: {
    type: Number,
    default: 0
  },
  deriveModel: {
    type: Object as PropType<defs.DerivedDevelopDto>,
    default: () => {}
  },
  timeframeArray: {
    type: Array as PropType<any[]>,
    default: () => []
  }
});

//上线状态
const route = useRoute();
let status = ref<any>(route.query.status);
let emit = defineEmits(['getDerivedDimList']);

const state = reactive({
  popupVisible: false, //指标弹出框
  metricsDefindList: [] as any[], //指标定义中的列表
  metricsDevelopList: [] as any[], //指标开发中的列表
  modelList: [] as any[], //模型列表
  periodList: [] as any[], //统计周期列表
  findList: [] as any[], //维度查询id对象数组
  drawerVisible: false, //指标抽屉
  drawerTitle: '', //抽屉标题
  node: null as any, // 获取到节点
  endIndex: '', // 光标最后停留位置
  position: {
    x: 0,
    y: 0
  }, // 弹窗显示位置
  factorListIndex: -1, //编辑指标定位下标
  createBtnIndex: 0, //创建指标下标
  btnClickArray: [] as any //单击方法
});

//运算符下拉
const symbolList = [
  { label: '+', value: '+' },
  { label: '-', value: '-' },
  { label: '*', value: '*' },
  { label: '/', value: '/' },
  { label: '(', value: '(' },
  { label: ')', value: ')' }
];
//计算规则内容ref
const ruleRef = ref();
//指标列表选择弹窗ref
const rulePopoverRef = ref();
//运算符号弹窗ref
const signRef = ref();
//指标因子对象
const derivedDevelopFactor = ref<defs.DerivedDevelopFactorDto>({});
//维度时间频度是否聚合
const metricsFilter = ref<defs.MetricsFilterDto>({});

//详情处理
const getDerivedDetail = (obj: defs.DerivedDevelopDto) => {
  let factorList = obj.factorList;
  let countRules = obj.countRules;

  //数据处理
  if (factorList) {
    let findList = factorList.map((item) => {
      return { metricsId: item.metricsId, modelId: item.modelId };
    });
    state.findList = findList;

    //计算规则
    const div = createDivNode();
    if (countRules) {
      getCountRulesHtml(factorList, countRules, div, 0);
    }
    ruleRef.value.appendChild(div);

    //统计周期数组
    factorList.map((item) => {
      props.timeframeArray.push({
        metricsId: item.metricsId,
        modelId: item.countCycleDto?.unit
      });
    });
    //下标
    state.createBtnIndex = factorList.length;
  }
};
//计算规则html处理
const getCountRulesHtml = (
  factorList: any[],
  countRules: string,
  div: HTMLDivElement,
  arrayIndex: number
) => {
  //从指标因子列表中查找指标
  let item = factorList[arrayIndex];
  if (item && item.factorName && countRules) {
    //截取因子名称
    let index = countRules.indexOf(item.factorName);
    if (index != -1) {
      let nameIdnex = index + item.factorName.length;
      //按照顺序查找，before没有指标的字符
      let before = countRules.substring(0, index);
      let after = countRules.substring(nameIdnex, countRules.length);
      //指标之前的文本
      if (before) {
        const span = createTextSpanNode();
        span.textContent = before;
        div.appendChild(span);
      }
      //指标文本
      const atButton = createAtButton(item.factorName);
      div.appendChild(atButton);
      //有继续查找，没有加入零宽
      if (after) {
        getCountRulesHtml(factorList, after, div, arrayIndex + 1);
      } else {
        const span = createSpanNode();
        div.appendChild(span);
      }
    }
  } else {
    //没有指标，直接显示文本
    const span = createTextSpanNode();
    span.textContent = countRules;
    div.appendChild(span);
  }
};
//导出内容编辑ref
defineExpose({
  ruleRef: ruleRef
});
//匹配时间单位和时间周期
const periodUnit = (val?: string) => {
  if (val == 'same_day') {
    return 'day';
  } else if (val == 'same_week') {
    return 'week';
  } else if (val == 'same_month') {
    return 'month';
  } else if (val == 'same_quarter') {
    return 'quarter';
  } else if (val == 'same_year') {
    return 'year';
  }
};

//编辑指标抽屉
const editMertrics = (cnName: any, index?: number) => {
  state.drawerVisible = true;
  state.drawerTitle = cnName;
  state.factorListIndex = index!;
  if (props.deriveModel.factorList && index != undefined) {
    derivedDevelopFactor.value = _.cloneDeep(
      props.deriveModel.factorList[index]
    );
  }
};

// 光标位置提示
const rangeIndexInfo = () => {
  //获取编辑对象
  let selection = getSelection();
  if (selection) {
    //获取光标对象
    const range = selection.getRangeAt(0);
    //当前光标位置
    const curIndex = getCursorIndex();
    //当前节点对象
    const curNode: any = getRangeNode();

    //先删除所有提示
    let nodes = document.getElementsByClassName('placeholder-after');
    for (let i = 0; i < nodes.length; i++) {
      nodes[i].classList.remove('placeholder-after');
    }
    //默认插入一行div
    if (ruleRef.value.innerHTML == '') {
      const div = document.createElement('div');
      div.setAttribute('data-digitforce-node', 'element');
      const span = createSpanNode();
      div.appendChild(span);
      ruleRef.value.appendChild(div);
      range?.setStart(span, 0);
      range?.setEnd(span, 0);
    } else {
      //记录节点
      const node = getRangeNode();
      const endIndex: any = getCursorIndex();
      state.node = node;
      state.endIndex = endIndex;
    }
    //如果有换行符，清空
    // if (curNode.innerHTML == '<br>') {
    //   curNode.innerHTML = '\u200b';
    // }

    let contentLen = curNode.textContent.replace(/[\u200b]/g, '');
    //判断光标是否在最后
    if (curIndex == contentLen.length || contentLen.length == '') {
      if (
        curNode.nodeType == 3 &&
        curNode.parentElement &&
        curNode.parentElement.nextSibling == null &&
        curNode.parentElement.contentEditable != 'false'
      ) {
        curNode.parentElement.classList.add('placeholder-after');
      }
      if (curNode.nodeName == 'DIV') {
        curNode.children[0].classList.add('placeholder-after');
      }
      if (curNode.nodeName == 'SPAN') {
        curNode.classList.add('placeholder-after');
      }
    }
  }
};

// 获取光标位置
const getCursorIndex = () => {
  const selection = window.getSelection();
  return selection?.focusOffset; // 选择开始处 focusNode 的偏移量
};
// 获取节点
const getRangeNode = () => {
  const selection = window.getSelection();
  return selection?.focusNode; // 选择的结束节点
};
// 弹窗出现的位置
const getRangeRect = () => {
  const selection = window.getSelection();
  if (selection) {
    const range = selection.getRangeAt(0); // 是用于管理选择范围的通用对象
    const rect = range.getClientRects()[0]; // 择一些文本并将获得所选文本的范围
    return {
      x: rect.x,
      y: rect.y
    };
  }
  return {
    x: 0,
    y: 0
  };
};
//创建div节点
const createDivNode = () => {
  const div = document.createElement('div');
  div.setAttribute('data-digitforce-node', 'element');
  return div;
};
//创建span节点
const createSpanNode = () => {
  //默认零宽，空白标签，便于光标展示
  const span = document.createElement('span');
  span.setAttribute('data-digitforce-zero', 'n');
  span.textContent = '\u200b';
  return span;
};
//创建文本节点
const createTextSpanNode = () => {
  const span = document.createElement('span');
  span.setAttribute('data-digitforce-string', 'true');
  return span;
};
//替换零宽节点
const replaceZeroSpanNode = () => {
  let selection = window.getSelection();
  const forceNode = selection?.focusNode;
  let range = selection?.getRangeAt(0);

  const parentElement = forceNode?.parentElement?.parentElement;
  const el: any = forceNode?.parentElement;
  const textContent: any = forceNode?.textContent;
  let isZero = el?.getAttribute('data-digitforce-zero');
  //是零宽就替换成有的
  if (isZero == 'n' && textContent.replace(/[\u200b]/g, '')) {
    let span = createTextSpanNode();
    //替换占位符，并重新赋值
    span.textContent = textContent.replace(/[\u200b]/g, '');
    parentElement?.removeChild(el);
    parentElement?.appendChild(span);
    range?.setStart(span, 1);
    range?.setEnd(span, 1);
  }
  //只剩div元素，要加零宽
  if (
    forceNode?.nodeName == 'DIV' &&
    forceNode?.nodeType == 1 &&
    forceNode.textContent == ''
  ) {
    const span = createSpanNode();
    forceNode.textContent = '';
    forceNode.appendChild(span);
  }
};
//删除节点
const deleteSpanNode = (code: string) => {
  let selection = window.getSelection();
  const forceNode = selection?.focusNode;
  let parentElement: any = null;

  if (forceNode?.nodeType == 3) {
    parentElement = forceNode?.parentElement;
  } else if (forceNode?.nodeType == 1) {
    parentElement = forceNode;
  }
  //判断是否在最后
  if (parentElement?.getAttribute('data-digitforce-zero') == 'n') {
    if (
      (parentElement.className != 'placeholder-after' && code == 'Delete') ||
      code == 'Backspace'
    ) {
      parentElement.parentElement?.removeChild(parentElement);
    } else {
      const span = createSpanNode();
      parentElement.parentElement?.appendChild(span);
    }
  }
  //文本内容删空后，零宽替代
  if (
    parentElement?.getAttribute('data-digitforce-string') == 'true' &&
    parentElement.textContent.length == 1
  ) {
    const span = createSpanNode();
    parentElement.parentElement?.appendChild(span);
  }
};

// 是否展示 #
const showAt = () => {
  const node = getRangeNode();
  if (!node || node.nodeType !== Node.TEXT_NODE) return false;
  const content = node.textContent || '';
  const regx = /#([^#\s]*)$/;
  const match = regx.exec(content.slice(0, getCursorIndex()));
  return match && match.length === 2;
};

//是否展示运算符号
const showSign = () => {
  const node = getRangeNode();
  if (!node || node.nodeType !== Node.TEXT_NODE) return false;
  const content = node.textContent || '';
  let str = content.slice(0, getCursorIndex());
  str = str.substring(str.length - 1, str.length);
  let isHas = symbolList.some((item) => item.value == str);
  return isHas;
};

//替换运算符号
const replaceSign = (value: string) => {
  const node = state.node;
  const content = node.textContent || '';
  let index: any = state.endIndex;
  //替换字符
  if (index != undefined) {
    const strAry = content.split('');
    strAry[index - 1] = value;
    node.textContent = strAry.join('');
  }
  // 重置光标的位置
  const range = new Range();
  const selection = window.getSelection();
  range.setStart(node, index);
  range.setEnd(node, index);
  selection?.removeAllRanges();
  selection?.addRange(range);
  //关闭弹出框
  signRef.value.style.display = 'none';
};

// 创建标签
const createAtButton = (cnName: any) => {
  const ic = document.createElement('i');
  ic.className = 'icon-metricsx-custom icon-metricsx-qiantaiguanli custom-size';
  const btn = document.createElement('span');
  btn.style.display = 'inline-block';
  //因子数组的长度作为，设置id，用更新dom节点
  let factorListIndex = state.createBtnIndex;
  btn.id = 'mertric' + factorListIndex;
  btn.className = 'mertric-btn';
  btn.contentEditable = 'false';
  btn.textContent = `${cnName}`;

  btn.appendChild(ic);
  //保存单击方法，待解除使用
  let btnClick = () => {
    editMertrics(cnName, factorListIndex);
  };
  state.btnClickArray[factorListIndex] = btnClick;
  btn.addEventListener('click', btnClick);
  //增加下标
  state.createBtnIndex = factorListIndex + 1;
  return btn;
};
//替换符号
const replaceString = (raw: any, replacer: any) => {
  return raw.replace(/#([^#\s]*)$/, replacer);
};
// #插入指标
const addMertrics = async (item: any) => {
  const node = state.node;
  const content = ruleRef.value.innerText.replace(/[\u200b]/g, '');

  let nextTextNode: any = null;
  let previousTextNode = null;
  //当前光标定位的节点，不是按钮标签
  if (
    node &&
    node.parentNode.className != 'mertric-btn' &&
    content != '' &&
    item
  ) {
    const content = node.textContent || '';
    const endIndex = state.endIndex;
    //前面字符
    const preSlice = replaceString(content.slice(0, endIndex), '');
    //后面字符
    const restSlice = content.slice(endIndex);
    //判断父节点，3类型节点是文本取父级的父级，1是标签取父级
    const parentNode =
      node.nodeType == 3 ? node.parentNode.parentNode : node.parentNode;
    //下一个节点
    const nextNode =
      node.nodeType == 3 ? node.parentNode.nextSibling : node.nextSibling;
    //有内容赋值，没有创建零宽标签占位
    if (preSlice.replace(/[\u200b]/g, '') == '') {
      previousTextNode = createSpanNode();
    } else {
      previousTextNode = createTextSpanNode();
      previousTextNode.textContent = preSlice;
    }
    if (restSlice.replace(/[\u200b]/g, '') == '') {
      nextTextNode = createSpanNode();
    } else {
      nextTextNode = createTextSpanNode();
      nextTextNode.textContent = restSlice;
    }
    //创建按钮标签
    const atButton = createAtButton(item.cnName);
    //删除之前的#号
    parentNode.removeChild(node.nodeType == 3 ? node.parentNode : node);
    // 插在文本框中
    if (nextNode) {
      parentNode.insertBefore(previousTextNode, nextNode);
      parentNode.insertBefore(atButton, nextNode);
      parentNode.insertBefore(nextTextNode, nextNode);
    } else {
      parentNode.appendChild(previousTextNode);
      parentNode.appendChild(atButton);
      parentNode.appendChild(nextTextNode);
    }
  } else {
    //第一次没有内容的时候
    if (ruleRef.value.innerHTML == '') {
      const div = createDivNode();
      const span = createSpanNode();
      div.appendChild(span);
      ruleRef.value.appendChild(div);
    }
    const atButton = createAtButton(item.cnName);
    nextTextNode = createSpanNode();
    ruleRef.value.children[0].appendChild(atButton);
    ruleRef.value.children[0].appendChild(nextTextNode);
  }
  // 重置光标的位置
  const range = new Range();
  const selection = window.getSelection();
  range.setStart(nextTextNode, 0);
  range.setEnd(nextTextNode, 0);
  selection?.removeAllRanges();
  selection?.addRange(range);

  //关闭弹出框
  rulePopoverRef.value.style.display = 'none';
  state.popupVisible = false;
  rangeIndexInfo();
  await setDefault(item);
};

//设置因子默认值
const setDefault = async (item: any) => {
  //查询模型列表
  await getModelList(item.id);

  derivedDevelopFactor.value.factorName = item.cnName;
  derivedDevelopFactor.value.metricsId = item.id;
  derivedDevelopFactor.value.modelId = state.modelList[0]?.id;
  derivedDevelopFactor.value.limitDto = undefined;
  //时间频度和表字段
  await getDimensionList(item.id, derivedDevelopFactor.value.modelId);
  //时间频度默认值处理,判断是否聚合,没有聚合可以选择
  if (metricsFilter.value.ifGroupBy == 0) {
    let obj = state.periodList.find(
      (item) => item.value.indexOf(metricsFilter.value.timeframe) != -1
    );
    derivedDevelopFactor.value.countCycleDto = {};
    if (obj) {
      derivedDevelopFactor.value.countCycleDto.type = obj.value;
      derivedDevelopFactor.value.countCycleDto.unit =
        metricsFilter.value.timeframe;
    } else {
      derivedDevelopFactor.value.countCycleDto.type = state.periodList[0].value;
      derivedDevelopFactor.value.countCycleDto.unit = periodUnit(
        state.periodList[0].value
      );
    }
  } else {
    derivedDevelopFactor.value.countCycleDto = undefined;
  }
  //统计周期数组
  let time = {
    id: item.id,
    timeframe: metricsFilter.value.timeframe
  };
  props.timeframeArray.push(time);

  //指标因子预存
  props.deriveModel.factorList?.push(_.cloneDeep(derivedDevelopFactor.value));
  //查询可用维度列表
  let findDim = {
    metricsId: derivedDevelopFactor.value.metricsId,
    modelId: derivedDevelopFactor.value.modelId
  };
  state.findList.push(findDim);
  emit('getDerivedDimList', state.findList);
};

//更新指标节点
const updateNode = () => {
  //获取节点dom对象
  if (props.deriveModel.factorList) {
    let factorListIndex = state.factorListIndex;
    let id = 'mertric' + factorListIndex;
    let dom = document.getElementById(id);
    if (dom) {
      const ic = document.createElement('i');
      ic.className =
        'icon-metricsx-custom icon-metricsx-qiantaiguanli custom-size';
      let name: any = derivedDevelopFactor.value.factorName;
      dom.textContent = name;
      //解除事件，在绑定
      let btnClick = state.btnClickArray[factorListIndex];
      dom.removeEventListener('click', btnClick);
      dom.addEventListener('click', () => {
        editMertrics(name, factorListIndex);
      });
      dom.appendChild(ic);
    }

    //因子数组
    props.deriveModel.factorList[factorListIndex] = _.cloneDeep(
      derivedDevelopFactor.value
    );

    //统计周期数组
    let oldTime = props.timeframeArray[factorListIndex].timeframe;
    let newTime =
      derivedDevelopFactor.value.countCycleDto?.unit ||
      metricsFilter.value.timeframe;
    let time = {
      id: derivedDevelopFactor.value.metricsId,
      timeframe: newTime || oldTime
    };

    props.timeframeArray[factorListIndex] = time;
    //查询可用维度列表
    let findDim = {
      metricsId: derivedDevelopFactor.value.metricsId,
      modelId: derivedDevelopFactor.value.modelId
    };
    state.findList[factorListIndex] = findDim;
    emit('getDerivedDimList', state.findList);
  }
  state.node = null;
};

// 键盘改变事件
const handleChange = (e: any) => {
  //删除时
  if (
    e.inputType === 'deleteContentBackward' ||
    e.inputType === 'deleteContentForward'
  ) {
    for (let i = 0; i < state.createBtnIndex; i++) {
      let id = 'mertric' + i;
      let dom = document.getElementById(id);
      //如果没找到表示已经删除
      if (!dom) {
        if (props.deriveModel.factorList) {
          props.deriveModel.factorList[i] = undefined as any;
          //统计周期数组
          props.timeframeArray[i] = undefined;
          //查询可用维度列表
          state.findList[i] = undefined;
        }
      }
    }
    //删除后查询一次
    emit('getDerivedDimList', state.findList);
    return false;
  }
  if (showAt()) {
    state.position = getRangeRect();
    //距离屏幕右侧小于弹出框的宽度,326弹出框宽度，32px偏移
    let left = state.position.x;
    let top = state.position.y + 20;
    if (document.body.clientWidth - left < 326 + 32) {
      left = document.body.clientWidth - 326 - 32;
    }
    if (document.body.clientHeight - top < 546 + 32) {
      top = document.body.clientHeight - 546 - 32;
    }
    rulePopoverRef.value.style.display = 'block';
    rulePopoverRef.value.style.left = left + 'px';
    rulePopoverRef.value.style.top = top + 'px';
  } else if (showSign()) {
    state.position = getRangeRect();
    //距离屏幕右侧小于弹出框的宽度,27弹出框宽度，32px偏移
    let left = state.position.x;
    let top = state.position.y + 20;
    if (document.body.clientWidth - left < 27 + 32) {
      left = document.body.clientWidth - 27 - 32;
    }
    if (document.body.clientHeight - top < 156 + 32) {
      top = document.body.clientHeight - 156 - 32;
    }
    signRef.value.style.display = 'block';
    signRef.value.style.left = left + 'px';
    signRef.value.style.top = top + 'px';
  } else {
    rulePopoverRef.value.style.display = 'none';
    signRef.value.style.display = 'none';
    //更新节点
    replaceZeroSpanNode();
  }
};
// 键盘按下事件
const handleKeyDown = (e: any) => {
  //禁止换行
  if(e.code === 'Enter'){
    e.preventDefault();
  }
  //删除时替换所有的0占位符
  if (e.code === 'Backspace' || e.code === 'Delete') {
    deleteSpanNode(e.code);
  }
};
//焦点离开
const handleBlur = () => {
  const content = ruleRef.value.innerText.replace(/[\u200b]/g, '');
  //焦点离开，内容为空，清空里面的标签
  if (content == '') {
    ruleRef.value.innerHTML = '';
  }
};

//获取指标定义列表
const getMetricsDefindList = async (id: any) => {
  const { code, data } = await API.metrics.getMetricsGetDerivedOfMetricsById({
    id
  });
  if (code == 200 && Array.isArray(data)) {
    state.metricsDefindList = data;
  }
};

//获取指标开发列表
const getMetricsDevelopList = async (cnName: any) => {
  const { code, data } = await API.metrics.getMetricsGetDevelopMetricsList({
    cnName
  });
  if (code == 200 && Array.isArray(data)) {
    state.metricsDevelopList = data;
    state.metricsDevelopList.map((item) => {
      item.disabled = item.developStatus == 0 || item.reviewStatus != 5;
    });
  }
};

//获取模型列表
const getModelList = async (id: any) => {
  const { code, data } = await API.dataModel.getGetDevelopMetricsModelListById({
    id
  });
  if (code == 200 && Array.isArray(data)) {
    state.modelList = data;
  }
};

//获取表字段和时间频度列表
const getDimensionList = async (metricsId: any, modelId: any) => {
  const { code, data } =
    await API.metricsModelRelation.getGetMetricsOfDimensionList({
      metricsId,
      modelId
    });
  if (code == 200 && data) {
    metricsFilter.value = data;
    if (data.queryFieldList) {
      //业务范围
      let modelTableColumnList = _.cloneDeep(data.queryFieldList);
      //下拉框结构
      modelTableColumnList.map((item: any) => {
        item.value = item.columnName + item.tableName;
        item.label = item.tableFieldDesc;
        item.tableFieldName = item.columnName;
        item.ifBindDimension =
          item.ifBindDimension == null ? 0 : item.ifBindDimension;
        item.ifPartition = item.ifPartition == null ? 0 : item.ifPartition;
      });
      //业务范围选择，去掉日期类型
      modelTableColumnList = modelTableColumnList.filter(
        (item: any) => item.tableFieldType != 'DATETIME'
      );
      metricsFilter.value.queryFieldList = modelTableColumnList;
    }
  }
};

// 查询统计周期列表
const getCountType = async () => {
  const { code, data } = await API.enumBao.getGetCountType();
  if (code === 200 && Array.isArray(data)) {
    state.periodList = data;
  }
};

onMounted(() => {
  getMetricsDefindList(props.metricsId);
  getMetricsDevelopList('');
  getCountType();
});

//详情处理
watch(
  () => props.deriveModel,
  (val) => {
    if (val) {
      getDerivedDetail(val);
    }
  }
);
</script>
<template>
  <div class="textarea-div">
    <div
      class="rules"
      :contenteditable="status != 1"
      placeholder="输入#号可插入指标"
      @keyup="rangeIndexInfo"
      @keydown="handleKeyDown"
      @input="handleChange"
      @click="rangeIndexInfo"
      @blur="handleBlur"
      ref="ruleRef"
    ></div>
    <a-popover
      trigger="click"
      position="left"
      v-model:popup-visible="state.popupVisible"
      content-class="rule-popover"
    >
      <div class="add-html-btn">
        <a-button type="text" :disabled="status == 1"
          >&lt;/&gt;插入指标</a-button
        >
      </div>
      <template #content>
        <MertricsTab
          @add-mertrics="addMertrics"
          @search-mertrics="getMetricsDevelopList"
          :metricsDefindList="state.metricsDefindList"
          :metricsDevelopList="state.metricsDevelopList"
        />
      </template>
    </a-popover>
    <div class="rule-popover" ref="rulePopoverRef">
      <MertricsTab
        @add-mertrics="addMertrics"
        @search-mertrics="getMetricsDevelopList"
        :metricsDefindList="state.metricsDefindList"
        :metricsDevelopList="state.metricsDevelopList"
      />
    </div>
    <div ref="signRef" class="symbol-list-wrap">
      <div v-for="v in symbolList" :key="v.value" @click="replaceSign(v.value)">
        {{ v.label }}
      </div>
    </div>
    <MertricsDrawer
      v-model:visible="state.drawerVisible"
      :drawerTitle="state.drawerTitle"
      :deriveModel="deriveModel"
      :derivedDevelopFactor="derivedDevelopFactor"
      :metricsOptions="state.metricsDevelopList"
      :metricsFilter="metricsFilter"
      :periodList="state.periodList"
      @getDimensionList="getDimensionList"
      @updateNode="updateNode"
    ></MertricsDrawer>
  </div>
</template>
<style lang="scss">
.rule-popover {
  width: 326px;
  padding: 14px 0;
}
</style>
<style lang="scss" scoped>
@import './index.scss';
</style>